@file:OptIn(ExperimentalComposeUiApi::class)

package com.zykj.evaluation.ui.home

import android.app.Activity
import android.graphics.Rect
import android.view.View
import android.view.Window
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import java.util.concurrent.atomic.AtomicBoolean


@Composable
fun CustomTextField(
    modifier: Modifier = Modifier,
    hint: String? = null,
    onTextChange: String.() -> Unit = {},
    leadingIcon: @Composable (() -> Unit)? = null,
    keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
    keyboardActions: String.() -> Unit = {},
    textFieldStyle: TextStyle,
    hintTextStyle: TextStyle,
) {
    var text by remember { mutableStateOf("") }
    val focusManager = LocalFocusManager.current
    Row(
        modifier.padding(end = 3.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        leadingIcon?.invoke()
        Spacer(modifier = Modifier.width(4.dp))
        BasicTextField(
            value = text,
            onValueChange = {
                text = it
                onTextChange.invoke(text)
            },
            cursorBrush = SolidColor(MaterialTheme.colorScheme.primaryContainer),
            singleLine = true,
            modifier = Modifier
                .weight(1f),
            textStyle = textFieldStyle,
            decorationBox = { innerTextField ->
                if (text.isEmpty())
                    Box(
                        modifier = Modifier
                            .fillMaxHeight(),
                        contentAlignment = Alignment.CenterStart
                    ) {
                        innerTextField()
                        Text(
                            hint ?: "",
                            modifier = Modifier
                                .fillMaxWidth(),
                            style = hintTextStyle,
                        )
                    } else innerTextField()
            },
            keyboardActions = KeyboardActions {
                keyboardActions(text)
            },
            keyboardOptions = keyboardOptions
        )
    }
}

/**
 * 给页面添加虚拟键盘可见性的监听事件, 沉浸式页面下使用
 * @param onKeyboardVisible 键盘是否显示的事件
 */
fun Activity.addInputKeyboardVisibleListener(
    rootContainer: View,
    onKeyboardVisible: (Boolean) -> Unit
) {
    val isKeyboardVisible = AtomicBoolean(false)
    val androidContentView = window.decorView.findViewById<View>(Window.ID_ANDROID_CONTENT)
    val hasBottomNavigation = AtomicBoolean(false)
    var keyboardHeight = 0 //键盘高度
    window.decorView.setOnApplyWindowInsetsListener { _, windowInsets ->
        hasBottomNavigation.set(
            WindowInsetsCompat.toWindowInsetsCompat(windowInsets)
                .isVisible(WindowInsetsCompat.Type.navigationBars())
        )
        val insets = WindowInsetsCompat.toWindowInsetsCompat(windowInsets)
            .getInsets(WindowInsetsCompat.Type.ime())
        keyboardHeight = insets.bottom  //获取IME键盘的高度
        return@setOnApplyWindowInsetsListener windowInsets
    }
    androidContentView.viewTreeObserver.addOnGlobalLayoutListener {
        val decorViewRect = Rect()
        window.decorView.getWindowVisibleDisplayFrame(decorViewRect)
        val diffPadding = when {
            hasBottomNavigation.get() && keyboardHeight > 0 -> keyboardHeight
            hasBottomNavigation.get() && keyboardHeight == 0 -> 22
            else -> keyboardHeight
        }
        if (diffPadding > 0) {
            if (!isKeyboardVisible.getAndSet(true))
                onKeyboardVisible(true)
            if (diffPadding != rootContainer.paddingBottom)
                rootContainer.updatePadding(bottom = diffPadding)
        } else {
            if (rootContainer.paddingBottom != 0)
                rootContainer.updatePadding(bottom = 0)
            if (isKeyboardVisible.getAndSet(false))
                onKeyboardVisible(false)
        }
    }
}